<!--
 * 电梯导航、联动菜单
 * @作者: 陈老师儿~
 * @手机: 18560000860
 -->
<template>
    <view class="pure-elevator-group" :class="classes" :style="styles">
        <view class="pure-elevator-group-content" :id="id">
            <slot></slot>
        </view>
    </view>
</template>

<script>
    import props from "./props.js";
    export default {
        options: {
            // 将自定义节点设置成虚拟的
            // 头条、飞书：因为合并后丢失事件和 'provide/inject'
            // 京东：因为合并后不能合并外层 'class'
            // 百度：因为合并后会在控制台疯狂报警告
            // #ifndef MP-TOUTIAO || MP-LARK || MP-JD || MP-BAIDU
            virtualHost: true,
            // #endif

            // 组件样式隔离
            styleIsolation: "apply-shared",

            // 允许使用多个插槽
            multipleSlots: true,
        },
        props,
        emits: [],
        inject: {
            // 添加组
            addGroup: {
                from: "addGroup",
                default: () => {
                    return () => {};
                },
            },

            // 移除组
            removeGroup: {
                from: "removeGroup",
                default: () => {
                    return () => {};
                },
            },
        },
        data() {
            return {
                id: "", // ID
                isQuering: false, // 是否正在查询
                isUpdating: false, // 是否需要更新
                debug: false,
            };
        },
        computed: {
            // classes
            classes() {
                const classes = [];
                return classes;
            },

            // styles
            styles() {
                const styles = {};
                return styles;
            },
        },
        watch: {
            // 数据变化后
            group: {
                handler() {
                    // 重新初始化
                    this.init();
                },
                deep: true,
            },
        },
        created() {
            // 初始化ID
            this.initID();
        },
        mounted() {
            // 初始化
            this.init();
        },
        beforeUnmount() {
            // 移除此项
            this.removeGroup(this.id);
        },
        methods: {
            // 初始化ID
            initID() {
                this.id = `PureElevatorGroup_${Date.now()}_${this.randomString()}`;
            },

            // 初始化
            async init() {
                // 正在初始化
                if (this.isQuering) {
                    this.isUpdating = true;
                    return;
                }

                // 更新状态
                this.isQuering = true;

                // 如果 v-if 了，得等一下
                await this.$nextTick();
                await this.sleep();

                // 获取节点信息
                const rect = await this.getRect();

                // 更新状态
                this.isQuering = false;

                // 判断是否需要更新
                // 需要更新就直接更新，先不添加
                if (this.isUpdating) {
                    this.isUpdating = false;
                    this.init();
                    return;
                }

                // 否则就添加最新的节点信息
                this.addGroup(this.id, {
                    id: this.id,
                    value: this.value,
                    floorValue: this.floorValue,
                    rect: rect,
                    getRect: this.getRect,
                });
            },

            // 获取节点信息
            getRect() {
                return new Promise((resolve, reject) => {
                    uni.createSelectorQuery()
                        .in(this)
                        .select(`#${this.id}`)
                        .boundingClientRect((rect) => {
                            resolve(rect);
                        })
                        .exec();
                });
            },

            // 生成一个36位的随机字符串
            randomString() {
                return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
            },

            // Sleep
            sleep(time = 50) {
                return new Promise((resolve) => {
                    let timer = setTimeout(() => {
                        clearTimeout(timer);
                        resolve();
                    }, time);
                });
            },
        },
    };
</script>

<style lang="scss" scoped>
    @import "./style.css";
</style>
